package com.vogue.supplymall.entmanagement.domain.service.impl;

import com.vogue.ssm.database.dao.BaseDao;
import com.vogue.ssm.database.util.DealStatus;
import com.vogue.supplymall.common.domain.dto.LicenceShopSearchInfo;
import com.vogue.supplymall.common.domain.dto.SearchInfo;
import com.vogue.supplymall.common.domain.dto.UploadInfo;
import com.vogue.supplymall.common.domain.dto.UserInfo;
import com.vogue.supplymall.common.domain.tool.MessageSourceUtils;
import com.vogue.supplymall.common.exception.DataNotFindException;
import com.vogue.supplymall.entmanagement.exception.ShopDisposingException;
import com.vogue.supplymall.entmanagement.domain.bean.ConstantBean;
import com.vogue.supplymall.entmanagement.domain.dao.LicenceApplyDao;
import com.vogue.supplymall.entmanagement.domain.dao.LicenceApplyDetailDao;
import com.vogue.supplymall.entmanagement.domain.dao.LicenceTypeDao;
import com.vogue.supplymall.entmanagement.domain.dto.LicenceApplyDTO;
import com.vogue.supplymall.entmanagement.domain.dto.LicenceApplyDetailDTO;
import com.vogue.supplymall.entmanagement.domain.dto.LicenceApplyEditDTO;
import com.vogue.supplymall.entmanagement.domain.model.LicenceApply;
import com.vogue.supplymall.entmanagement.domain.model.LicenceApplyDetail;
import com.vogue.supplymall.entmanagement.domain.service.LicenceApplyService;
import com.vogue.supplymall.shop.domain.model.Shop;
import com.vogue.supplymall.shop.domain.service.ShopService;
import com.vogue.supplymall.upload.domain.service.UploadService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.ParseException;
import java.util.*;

@Service("licenceApplyService")
public class LicenceApplyServiceImpl extends BaseServiceImpl<LicenceApply, Long> implements LicenceApplyService {

    public static Logger logger = LoggerFactory.getLogger(LicenceApplyServiceImpl.class);

    @Resource
    private LicenceApplyDao licenceApplyDao;

    @Resource
    private ShopService shopService;

    @Resource
    private LicenceApplyDetailDao licenceApplyDetailDao;

    @Resource
    private UploadService uploadService;

    @Resource
    private LicenceTypeDao licenceTypeDao;

    @Autowired
    protected MessageSourceUtils messageSourceUtils;

    public LicenceApplyServiceImpl(BaseDao<LicenceApply, Long> baseDao) {
        super(baseDao);
    }

    @Override
    public List<Map<String, Object>> findShopList(LicenceShopSearchInfo licenceShopSearchInfo) {
        return licenceApplyDao.findShopList(licenceShopSearchInfo);
    }

    @Override
    public List<Map<String, Object>> findWarning(LicenceShopSearchInfo licenceShopSearchInfo) {
        return licenceApplyDao.findWarning(licenceShopSearchInfo);
    }

    @Override
    public List<Map<String, Object>> findLABySyscodeid(SearchInfo searchInfo) {
        StringBuilder ids = new StringBuilder();
        String shopIds = "";

        Long syscodeId = searchInfo.getSyscodeid();
        if (syscodeId == null || syscodeId == 0L) {
            UserInfo info = (UserInfo) SecurityUtils.getSubject().getPrincipal();
            syscodeId = info.getSyscodeid();
            searchInfo.setSyscodeid(syscodeId);
        }

        //得到已开通的门店状态信息
        List<LicenceApply> laList = licenceApplyDao.findLABySyscodeid(syscodeId);

        //得到已开通的门店id
        for (LicenceApply la : laList) {
            /*if (ids.indexOf(la.getShopid().toString()) < 0) {
                ids.append(la.getShopid())
                        .append(",");
            }*/
            if (ids.indexOf(la.getMatchid().toString()) < 0) {
                ids.append(la.getMatchid())
                        .append(",");
            }
        }

        if (StringUtils.isNotBlank(ids.toString())) {
            shopIds = ids.toString();
            shopIds = shopIds.substring(0, shopIds.length() - 1);
        }

        //将参数信息整合进searchInfo中
        searchInfo.setParamCol(shopIds);

        //得到门店信息
        List<Map<String, Object>> shopList = shopService.findLicenceShopBySql(searchInfo);

        return shopList;
    }

    @Override
    public LicenceApplyEditDTO findShopApply(Long shopid) {
    	DealStatus.kacha();
        Shop shop = shopService.selectOneByWhr("id="+shopid);
//    	Shop shop = shopService.get(shopid);
        List<Map<String, Object>> list = licenceApplyDao.findShopApply(shopid, shop.getSyscodeid(), shop.getMatchid());
        LicenceApplyEditDTO editDTO = new LicenceApplyEditDTO();        
        list.parallelStream().forEachOrdered((map) -> {
            LicenceApplyDTO applyDTO = null;
            //如果是当前记录
            if (ConstantBean.EnumLicenceApplyType.CURRENT.getCode() ==
                    Integer.parseInt(map.get("applytype").toString())) {
                applyDTO = editDTO.getCurrentDTO();
                if (applyDTO == null) {
                    applyDTO = newLicenceApplyDTO(map, shop);
                    editDTO.setCurrentDTO(applyDTO);
                }
            } else if (ConstantBean.EnumLicenceApplyType.RENEW.getCode() ==
                    Integer.parseInt(map.get("applytype").toString())) {//续约记录
                applyDTO = editDTO.getRenewDTO();
                if (applyDTO == null) {
                    applyDTO = newLicenceApplyDTO(map, shop);
                    editDTO.setRenewDTO(applyDTO);
                }
            }

            LicenceApplyDetailDTO detailDTO = new LicenceApplyDetailDTO();
            detailDTO.setId(map.get("detailid").toString());
            detailDTO.setLicencetypeid(map.get("licencetypeid").toString());
            detailDTO.setLicencetypename((String) map.get("licencetypename"));
            detailDTO.setBegindate(ConstantBean.dateTimeFormatter.format((Date) map.get("begindate")));
            detailDTO.setEnddate(ConstantBean.dateTimeFormatter.format((Date) map.get("enddate")));
            detailDTO.setApplystatue(Integer.valueOf(map.get("dapplystatue").toString()));
            detailDTO.setUrl((String) map.get("url"));

            List<LicenceApplyDetailDTO> detailList = applyDTO.getDetailList();
            detailList.add(detailDTO);
            applyDTO.setDetailList(detailList);
        });
        return editDTO;
    }

    private LicenceApplyDTO newLicenceApplyDTO(Map<String, Object> map, Shop shop) {
        LicenceApplyDTO applyDTO = new LicenceApplyDTO();
        applyDTO.setShopid(shop.getId().toString());
        applyDTO.setShopname(shop.getName());
        applyDTO.setApplytype(Integer.valueOf(map.get("applytype").toString()));
        applyDTO.setId(map.get("applyid").toString());
        applyDTO.setSodid(map.get("sodid").toString());
        applyDTO.setSodname((String) map.get("sodname"));
        if (shop.getOpendate() != null) {
            applyDTO.setOpendate(ConstantBean.dateTimeFormatter.format(shop.getOpendate()));
        }
        applyDTO.setApplystatue(Integer.valueOf(map.get("applystatue").toString()));
        LicenceApply apply = licenceApplyDao.selectOneByWhr("shopid="
                + shop.getId()
                + " and applytype="
                + ConstantBean.EnumLicenceApplyType.HISTORY.getCode());
        applyDTO.setIsfirst(apply == null ? true : false);
        List<LicenceApplyDetailDTO> detailList = new ArrayList<>();
        applyDTO.setDetailList(detailList);
        return applyDTO;
    }

    @Override
    @Transactional
    public LicenceApplyEditDTO saveShopApply(LicenceApplyEditDTO dto) throws Exception {
        if (dto != null) {
            if (dto.getCurrentDTO() != null) {
                if (dto.getCurrentDTO().getApplytype() == null) {
                    dto.getCurrentDTO().setApplytype(ConstantBean.EnumLicenceApplyType.CURRENT.getCode());
                }
                dto.setCurrentDTO(saveShopApply(dto.getCurrentDTO()));
            }

            if (dto.getRenewDTO() != null) {
                if (dto.getRenewDTO().getApplytype() == null) {
                    dto.getRenewDTO().setApplytype(ConstantBean.EnumLicenceApplyType.RENEW.getCode());
                }
                dto.setRenewDTO(saveShopApply(dto.getRenewDTO()));
            }
        }
        return dto;
    }

    private LicenceApplyDTO saveShopApply(LicenceApplyDTO dto) throws Exception {
        LicenceApply apply = null;
        List<LicenceApplyDetail> applyDetial = null;
        if (dto.getId() == null) {
            apply = licenceApplyDao.selectOneByWhr("shopid=" + dto.getShopid() + " and applytype=" + dto.getApplytype().intValue());
            if (apply != null) {
                //该店铺正在处理中就稍候再试
                throw new ShopDisposingException();
            }
        }

        if (StringUtils.isEmpty(dto.getId())) {
            apply = new LicenceApply();     
            DealStatus.kacha();
            Shop shop = shopService.selectOneByWhr("id="+dto.getShopid());
            apply.setMatchid(shop.getMatchid());
            apply.setSyscodeid(shop.getSyscodeid());
            apply.setShopid(shop.getId());
        } else {
            apply = licenceApplyDao.get(Long.parseLong(dto.getId()));
            applyDetial = licenceApplyDetailDao.selectByWhr("applyid=" + dto.getId()
                    + " and disabledflag=0 ");
        }
        if (apply == null) {
            //找不到对应数据报异常
            throw new DataNotFindException(messageSourceUtils.getMessage(
                    com.vogue.supplymall.common.constant.ConstantBean.GLOBAL_SYSTEM
                            + "licenceApply", null));
        } else if (apply.getApplystatue() == ConstantBean.EnumLicenceApplyStatue.PASS.getCode()
                || apply.getApplystatue() == ConstantBean.EnumLicenceApplyStatue.TIMEOUT.getCode()) {
            //状态不可修改报异常
        } else {
            //保存开通日期
            if (dto.getIsfirst()) {
            	DealStatus.kacha();
                Shop shop = shopService.selectOneByWhr("id="+dto.getShopid());
//                Shop shop = shopService.get(Long.parseLong(dto.getShopid()));
                try {
                	DealStatus.kacha();
           		 	List<Shop> shopList = shopService.selectByWhr("matchid='"+shop.getMatchid()+"'");
                	for(Shop s : shopList) {
                		s.setOpendate(ConstantBean.dateTimeFormatter.parse(dto.getOpendate()));
                		DealStatus.kacha();
                		shopService.update(s);
                	}                   
                } catch (ParseException e) {
                    logger.error(">>> 开业日期转换错误:" + dto.getOpendate());
                    throw new Exception(e.getMessage());
                } catch (Exception e) {
                	logger.error(e.getMessage());
                	e.printStackTrace();
                    throw new Exception(e.getMessage());
                }                
            }

            //保存主记录信息
            apply.setApplystatue(ConstantBean.EnumLicenceApplyStatue.WAITING.getCode());
//            apply.setShopid(Long.parseLong(dto.getShopid()));
            apply.setApplytype(dto.getApplytype());
            apply.setDisabledflag(false);
            apply.setScopeid(Long.parseLong(dto.getSodid()));
            apply.setApplytype(dto.getApplytype());
//            UserInfo user = (UserInfo) SecurityUtils.getSubject().getPrincipal();
//            apply.setSyscodeid(user.getSyscodeid());
            if (apply.getId() == null) {
                licenceApplyDao.save(apply);
            } else {
                licenceApplyDao.update(apply);
            }
            dto.setId(apply.getId().toString());
            //保存明细
            for (LicenceApplyDetailDTO detailDTO : dto.getDetailList()) {
                LicenceApplyDetail detail = null;
                if (StringUtils.isEmpty(detailDTO.getId())) {
                	//如果id为空，先查一下同证照类型是否已经上传保存过明细，如果是则用已上传的
                	detail = licenceApplyDetailDao.selectOneByWhr("applyid="
                			+ apply.getId()
                			+ " and licencetypeid=" 
                			+ detailDTO.getLicencetypeid());
                	if(detail == null) {
                		detail = new LicenceApplyDetail();
                		detail.setApplystatue(ConstantBean.EnumLicenceApplyStatue.WAITING.getCode());
                	}                    
                } else {
                    detail = licenceApplyDetailDao.get(Long.parseLong(detailDTO.getId()));
                }
                if (detail != null) {
                	
                	if(checkApplyDetailModify(detail, detailDTO)) {
                		detail.setApplystatue(ConstantBean.EnumLicenceApplyStatue.WAITING.getCode());
                	}
                	
                    try {
                        detail.setBegindate(ConstantBean.dateTimeFormatter.parse(detailDTO.getBegindate()));
                    } catch (ParseException e) {
                        logger.error(">>> 日期转换错误:" + detailDTO.getBegindate());
                        e.printStackTrace();
                    }
                    try {
                        detail.setEnddate(ConstantBean.dateTimeFormatter.parse(detailDTO.getEnddate()));
                    } catch (ParseException e) {
                        logger.error(">>> 日期转换错误:" + detailDTO.getEnddate());
                        e.printStackTrace();
                    }
                    detail.setLicencetypeid(Long.parseLong(detailDTO.getLicencetypeid()));
                    detail.setShopid(apply.getShopid());
                    detail.setApplyid(apply.getId());
                    detail.setSyscodeid(apply.getSyscodeid());
                    detail.setMatchid(apply.getMatchid());                  
                    if (StringUtils.isNotEmpty(detail.getUrl()) &&
                            !detail.getUrl().equals(detailDTO.getUrl())) {
                        uploadService.removeResource(detail.getUrl());
                    }
                    detail.setUrl(detailDTO.getUrl());
                    if (detail.getId() == null) {
                        licenceApplyDetailDao.save(detail);
                    } else {
                        detail.setModifyDate(new Date());
                        licenceApplyDetailDao.update(detail);
                    }
                    detailDTO.setId(detail.getId().toString());
                    //如果发现图片是临时路径则重新上传生成正式的
                    if (detailDTO.getUrl().contains("/"
                            + com.vogue.supplymall.common.constant.ConstantBean.SYSTEM_NAME
                            + "/" + UploadService.TEMP_PATH)) {
                        UploadInfo uploadInfo = new UploadInfo();
                        uploadInfo.setDataid(detail.getId());
                        uploadInfo.setSourcepath(detailDTO.getUrl());
                        if (detailDTO.getUrl().contains(".")) {
                            uploadInfo.setExtension(detailDTO.getUrl().substring(detailDTO.getUrl().lastIndexOf(".") + 1));
                        }
                        uploadInfo.setModuleName(
                                com.vogue.supplymall.upload.domain.bean.ConstantBean.LICENCE_UPLOAD_MODULE_NAME
                                        + "/" + detail.getShopid()
                                        + "/" + detail.getLicencetypeid());
                        String url = uploadService.uploadResource(uploadInfo);
                        detail.setUrl(url);
                        detailDTO.setUrl(url);
                        detail.setModifyDate(new Date());
                        licenceApplyDetailDao.update(detail);
                    }
                }
            }
            //删除多余的数据库中的明细(数据库里存在但是本次提交保存中不包含)
            if (applyDetial != null) {
                for (LicenceApplyDetail detail : applyDetial) {
                    detail.setDisabledflag(true);
                    for (LicenceApplyDetailDTO detailDTO : dto.getDetailList()) {
                        if (detailDTO.getId().equals(detail.getId().toString())) {
                            detail.setDisabledflag(false);
                            break;
                        }
                    }
                    if (detail.isDisabledflag()) {
                        uploadService.removeResource(detail.getUrl());
                        licenceApplyDetailDao.delete(detail.getId());
                    }
                }
            }
        }
        return dto;
    }

    /**
     * 验证明细记录是否发生了修改
     * @return
     */
    private boolean checkApplyDetailModify(LicenceApplyDetail detail, LicenceApplyDetailDTO detailDTO) {
    	if(detailDTO.getBegindate() != null && detail.getBegindate() != null) {
    		try {
    			if(ConstantBean.dateTimeFormatter
        				.parse(detailDTO.getBegindate())
        				.compareTo(detail.getBegindate()) != 0) {
        			return true;
        		}
            } catch (ParseException e) {
                logger.error(">>> 日期转换错误:" + detailDTO.getBegindate());
                e.printStackTrace();
            }    		
    	}else {
    		return true;
    	}
    	
    	if(detailDTO.getEnddate() != null && detail.getEnddate() != null) {
    		try {
    			if(ConstantBean.dateTimeFormatter
        				.parse(detailDTO.getEnddate())
        				.compareTo(detail.getEnddate()) != 0) {
    				return true;
        		}
            } catch (ParseException e) {
                logger.error(">>> 日期转换错误:" + detailDTO.getEnddate());
                e.printStackTrace();
            }   
    	}else {
    		return true;
    	}
    	
    	if(detailDTO.getUrl()!=null) {
    		if(!detailDTO.getUrl().equals(detail.getUrl())) {
    			return true;
    		}
    	}else {
    		return true;
    	}
    	
    	return false;
    }
    @Override
    public void delCurApply(Long applyid) {
        // TODO Auto-generated method stub
        LicenceApply cur_apply = licenceApplyDao.get(applyid);
        LicenceApply new_apply = licenceApplyDao.selectOneByWhr("applytype=2 and shopid=" + cur_apply.getShopid());
        if (cur_apply != null) {
            licenceApplyDetailDao.deleteByWhr("applyid=" + cur_apply.getId());
            licenceApplyDao.delete(cur_apply.getId());
        }
        if (new_apply != null) {
            licenceApplyDetailDao.deleteByWhr("applyid=" + new_apply.getId());
            licenceApplyDao.delete(new_apply.getId());
        }
    }

    @Override
    public Long countByStatus(Long syscodeid, Integer status) {
        String sql = "select COUNT(id) count from licence_apply where syscodeid = #{syscodeid} and applystatue = #{status}";
        Map<String, Object> para = new HashMap<>();
        para.put("syscodeid", syscodeid);
        para.put("status", status);
        List<Map<String, Object>> result = licenceApplyDao.query0(sql, para);
        return result.size() > 0 ? new Long(result.get(0).get("count").toString()) : 0L;
    }

    @Override
    public Long countByType(Long syscodeid, Integer applytype) {
        String sql = "select COUNT(id) count from licence_apply where syscodeid = #{syscodeid} and applytype = #{applytype}";
        Map<String, Object> para = new HashMap<>();
        para.put("syscodeid", syscodeid);
        para.put("applytype", applytype);
        List<Map<String, Object>> result = licenceApplyDao.query0(sql, para);
        return result.size() > 0 ? new Long(result.get(0).get("count").toString()) : 0L;
    }
}
